<template>
  <m-modal
    :visible="visible"
    mask
    title="项目合并"
    ok-text="确定"
    cancel-text="取消"
    size="mini"
    :height="600"
    resizable
    class="v-select-source-project"
    :confirm-disabled="!model.sourceProjectPath"
    @ok="model.save()"
    @cancel="model.cancel()"
  >
    <div class="_container">
      <MAttrTip
        type="projectMerge"
        class="g-flex-0"
      ></MAttrTip>
      <div class="_body">
        <div class="_common g-bold">
          <div class="g-bolder _label">{{ $t("合并项目（源）") }}</div>
          <div class="g-flex">
            <el-select
              v-model="model.activeTab"
              class="tab-label"
              :suffix-icon="SelectSuffix"
            >
              <el-option
                value="local"
                :label="$t('本地项目')"
              ></el-option>
              <el-option
                v-if="model.isUserLogIn"
                value="online"
                :label="$t('协同项目')"
              ></el-option>
            </el-select>
            <!-- <div :class="{'selected-tab': activeTab === 'local'}" class="tab-label" @click="handleClickLocal">{{$t('本地项目')}}</div>
            <div  :class="{'selected-tab': activeTab === 'online'}" class="tab-label" @click="handleMergeOnline">{{$t('协同项目')}}</div> -->
          </div>
          <div
            class="_common-path g-pointer g-one-line"
            @click="model.handleSelectSourceProject"
          >
            <div class="g-text-ellipsis">{{ model.sourceProjectPath }}</div>
            <p
              v-if="!model.sourceProjectPath"
              class="g-disabled"
            >
              点击选择项目
            </p>
            <img
              v-if="model.activeTab === 'local'"
              src="statics/icons/app/iconmore.png"
              style="flex-shrink: 0"
            />
          </div>
        </div>
        <div class="_common g-bold">
          <div class="g-bolder _label">{{ $t("当前项目（目标）") }}</div>
          <div class="g-disabled _common-path _common-path_product">{{ model.targetProjectPath }}</div>
        </div>
      </div>
    </div>
  </m-modal>
</template>

<script lang="ts" setup>
import { mixPopup } from "@/common/Portal";
import { localFile } from "@/localFile/LocalFile";
import { onUnmounted, reactive, watch } from "vue";
import MAttrTip from "@/common/attrTip/AttrTip.vue";
import { sleep } from "@/util/common";
import { onlineProjectList } from "@/modules/cowork/modals/onlineProjectList";
import { projectService } from "../../service";
import { coworkService } from "@/modules/cowork/service/CoworkService";
import { ApiCode } from "@/constants/api";
import path from "path";
import { loading } from "@/common/Loading";
import { storage, StorageKey } from "@/util/Storage";
import SelectSuffix from "../../comps/common/SelectSuffix.vue";
import { usePortal } from "@/common/usePortal";
import { ProjectSpecification } from "@/constants/Enums";

let percentTimer: number | undefined;
let timer: number | undefined;
let leftTimer: number | undefined;
defineOptions(
  mixPopup(
    {
      name: "c-select-source-project"
    },
    { single: true }
  )
);

// const props = defineProps<{
//   targetProjectId:string
// }>();

const emit = defineEmits<{
  (event: "sure", data?: any): void;
  (event: "close", data?: any): void;
}>();

const { handleOk, visible, handleCancel } = usePortal(emit);
class Model {
  sourceProjectPath = "";
  onlineProjectPath = "";
  targetProjectPath = app.activeProject?.config.fullPath;
  activeTab = "local";
  uploadLoading = false;
  savePercent = 0;
  timeLeft = 0;
  blankResponse = 1;
  timeNumber = 0;
  delayTime = 1;
  uploadXmlFileSuccess = false;
  uploadingText = "项目转换中...";
  xmlFilePath = "";

  get isUserLogIn() {
    return !!app.global.user;
  }

  async resetLoading() {
    loading.close();
    this.savePercent = 0;
    this.uploadingText = "项目转换中...";
    this.uploadLoading = false;
    this.uploadXmlFileSuccess = false;
    window.clearInterval(timer);
    window.clearInterval(leftTimer);
    window.clearInterval(percentTimer);
  }
  save() {
    if (this.sourceProjectPath === this.targetProjectPath) {
      // TODO 这里的提示怎么提示当前窗口而不是主窗口？
      app.$confirm.popup({
        title: "提示",
        subTitle: "未发现任何差异",
        content: "两项目之间未发现任何差异，重新加载项目。",
        status: "warn",
        okText: "",
        cancelText: "关 闭"
      });
      return;
    }
    const filePath = this.onlineProjectPath || this.xmlFilePath || this.sourceProjectPath;
    handleOk(filePath);
  }
  async cancel() {
    if (this.onlineProjectPath) {
      await projectService.projectMergeRemoveTempFile(this.onlineProjectPath);
    }
    handleCancel();
  }
  async handleSelectSourceProject() {
    if (this.activeTab === "online") {
      this.handleMergeOnline();
    } else {
      const result = await localFile.chooseFile({
        title: "选择合并源项目文件",
        filters: [
          {
            name: "M-Arch Project File",
            extensions: ["md3", "md3t", "xml"]
          }
          // {
          //   name: 'M-Design Project File',
          //   extensions: ['md3', 'md3t']
          // },
          // {
          //   name: 'M-Cowork Project File',
          //   extensions: ['md3t']
          // }
        ]
      });
      if (result.canceled) return;
      // extname(name) === '.xml'
      this.sourceProjectPath = result.files[0].path;
      const fileName = path.basename(this.sourceProjectPath) as string;
      if (fileName.endsWith(".xml")) {
        // 先获取临时文件路径, 并去除后面的文件名
        let savePath = await projectService.projectMergeGetPath(fileName);
        const list = savePath.split("\\");
        list.pop();
        const newPath = list.join("\\");
        // 开始loading，期间通过接口查询loading进度
        this.uploadLoading = true;
        loading.popup(this.uploadingText);
        // 开始转换项目
        projectService.uploadXmlFile(this.sourceProjectPath, newPath).then(async res => {
          if (res.code === ApiCode.SUCCESS) {
            this.uploadXmlFileSuccess = true;
            this.xmlFilePath = savePath.replace(".xml", ".md3");
          } else {
            this.uploadXmlFileSuccess = false;
            this.resetLoading();
            this.sourceProjectPath = "";
            const ok = await app.$confirm.popup({
              title: "错误",
              subTitle: "项目转换失败？",
              content: "失败原因：" + (res.message || ""),
              status: "error",
              cancelText: "退出",
              okText: "重新选择项目"
            });
            if (ok.type == "ok") {
              this.handleSelectSourceProject();
            } else {
              return;
            }
          }
        });
        // .finally(() => { this.uploadLoading = false; });
      }
    }
  }
  async handleMergeOnline() {
    this.sourceProjectPath = "";
    this.activeTab = "online";
    const id = app.activeProject!.id;
    const projectSpecification = app.activeProject!.config.projectSpecification || ProjectSpecification.SYSML;
    const res = await onlineProjectList.popup({
      activeProjectId: id,
      isProjectMerge: true,
      activeProjectSpecification: projectSpecification
    });
    if (res.success) {
      this.onlineProjectPath = res.fullPath as string;
      this.sourceProjectPath = res.directory as string;
      const visible2 = await coworkService.getOnlineProjectVisible(res.projectId as string);
      if (!visible2) {
        app.$confirm
          .popup({
            title: "提示",
            subTitle: "无法进行项目合并",
            content: "所选协同项目内存在不可见包，无法进行项目合并操作。如需项目合并操作请升级权限并更新项目后再合并。",
            cancelText: "退出",
            okText: "重新选择项目",
            status: "error"
          })
          .then(async res1 => {
            if (res1.type === "ok") {
              await this.handleMergeOnline();
            }
          })
          .catch(async err => {
            if (err.type === "cancel") {
              await this.cancel();
            }
          });
      }
    }
  }
  handleClickLocal() {
    this.activeTab = "local";
    this.sourceProjectPath = "";
  }
}

const model = reactive(new Model());

watch(
  () => model.uploadLoading,
  newValue => {
    if (newValue) {
      const startTime = performance.now();
      timer = setInterval(async () => {
        const loadingData = await projectService.uploadProgressBar();
        if (model.uploadXmlFileSuccess) {
          console.log("model.uploadXmlFileSuccess", model.uploadXmlFileSuccess);
          window.clearInterval(timer);
          model.timeLeft = 1;
          model.savePercent = 100;
          const delayTime = (100 - model.savePercent) * 100;
          model.uploadingText = "转换完成,进度100%";
          loading.popup(model.uploadingText);
          await sleep(0.5); // 为了显示进度100%
          setTimeout(() => {
            model.resetLoading();
          }, delayTime);
        }
        if (loadingData.data && model.savePercent < 100) {
          model.blankResponse = 1;
          model.delayTime = 1;
          if (loadingData.data.flag && loadingData.data.executeRate < 99.6) {
            model.uploadingText = loadingData.data.executeName;
            const endTime = performance.now();
            const sec = (endTime - startTime) / 1000;
            const percentPerSec = (loadingData.data.executeRate - model.savePercent) / sec;
            const restPercent = 100 - loadingData.data.executeRate;
            model.timeLeft = restPercent / percentPerSec;
            model.savePercent = parseInt(loadingData.data.executeRate);
            model.uploadingText = `转换项目中，进度${model.savePercent}%`;
            loading.popup(model.uploadingText);
          } else {
            if (loadingData.data.executeRate > 99 && model.uploadXmlFileSuccess) {
              model.resetLoading();
            }
          }
          // 轮询结束
        } else {
          model.blankResponse++;
          if (model.blankResponse % 10 === 0) {
            model.timeLeft = model.timeNumber;
            model.delayTime = model.blankResponse / 10;
          }
        }
      }, 500) as unknown as number;
    } else {
      model.resetLoading();
    }
  }
);

watch(
  () => model.timeLeft,
  newValue => {
    window.clearInterval(leftTimer);
    if (newValue) {
      let sec = newValue;
      model.timeNumber = sec;
      leftTimer = setInterval(() => {
        if (sec <= 0) {
          window.clearInterval(leftTimer);
        }
      }, 1000 * model.delayTime) as unknown as number;
    }
  }
);

watch(
  () => model.savePercent,
  newValue => {
    window.clearInterval(percentTimer);
    if (model.savePercent < parseInt(newValue + "")) {
      percentTimer = setInterval(() => {
        if (model.savePercent < newValue) {
          model.savePercent++;
        } else {
          window.clearInterval(percentTimer);
        }
      }, 100) as unknown as number;
    }
  }
);

watch(
  () => model.activeTab,
  newValue => {
    if (newValue === "online") {
      model.handleMergeOnline();
    } else {
      model.handleClickLocal();
    }
  }
);
onUnmounted(() => {
  if (storage.get(StorageKey.projectMergePath)) {
    model.sourceProjectPath = storage.get(StorageKey.projectMergePath);
    storage.remove(StorageKey.projectMergePath);
  }
});
</script>

<style lang="scss">
@import "@/assets/css/theme.scss";
.v-select-source-project {
  ._container {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    ._body {
      padding: 24px;
      flex: 1 1 auto;
      ._common {
        display: flex;
        align-items: center;
        width: 100%;
        margin-bottom: 10px;
        > * {
          height: 27px;
          line-height: 27px;
        }
        ._label {
          width: 100px;
          text-align: right;
          margin-right: 5px;
        }
        ._common-path {
          padding-left: 5px;
          position: relative;
          border: 1px solid #e5e5e5;
          flex: 1;
          width: 100%;
          overflow: hidden;
          > img {
            position: absolute;
            right: 1%;
            top: 6px;
          }
        }
        ._common-path_product {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        .g-text-ellipsis {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          width: calc(100% - 20px);
        }
      }
    }
  }
  .tab-label {
    width: 85px;
    margin-right: -1px;
    .el-select__wrapper {
      min-height: 27px !important;
    }
  }
  .selected-tab {
    border-color: $theme-color;
    color: $theme-color;
  }
}
</style>
